using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Xml.Xsl;
using System.Xml.XPath;
using System.IO;
using System.Data;
using System.Globalization;
using System.Xml.Schema;


namespace sCicero
{
    public class xml : Base
    {
        private XmlDocument m_oXMLdoc;
        private XslCompiledTransform m_oXSLT;


        XmlReaderSettings xmlReaderSettings = new XmlReaderSettings();
        XmlSchema oSchema; 


        public xml()
        {
            oSchema = XmlSchema.Read(new XmlTextReader(new System.IO.StreamReader(GetType().Assembly.GetManifestResourceStream("sCicero.xsl.schema.xsd"))), xmlReaderSettings_ValidationEventHandler);
            xmlReaderSettings.CheckCharacters = true;
            xmlReaderSettings.CloseInput = true;
            xmlReaderSettings.Schemas.Add(oSchema);
            xmlReaderSettings.ValidationType = ValidationType.Schema;
            xmlReaderSettings.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;

            xmlReaderSettings.ValidationEventHandler += new ValidationEventHandler(xmlReaderSettings_ValidationEventHandler);
            

        }
        public XmlDocument LoadXMLFile(string m_sFileName)
        {
            m_oXMLdoc = new XmlDocument();
            System.IO.FileInfo oFi = new FileInfo(@m_sFileName);
            if (!oFi.Exists)
                m_oXMLdoc = LoadXmlresource(m_sFileName.Substring(0, m_sFileName.Length - 4));
            else
                m_oXMLdoc.Load(m_sFileName);
   
            return m_oXMLdoc;
        }
        public XPathDocument LoadXPathFile(string m_sFileName)
        {
            return new XPathDocument(m_sFileName);
        }
        public XPathNodeIterator QueryXML(XPathDocument oXpathInput, string sXpathExpression)
        {
            return (XPathNodeIterator)((XPathNavigator)oXpathInput.CreateNavigator()).Select(sXpathExpression);
        }

        public XmlDocument TranformDataToXML(DataTable m_oDataTable)
        {
            StringWriter sw = new StringWriter(new CultureInfo("sv-SE"));
            m_oXMLdoc = new XmlDocument();
            m_oDataTable.WriteXml(sw);
            m_oXMLdoc.LoadXml(sw.ToString());
            return m_oXMLdoc;

        }
        public string TransformXMLtoString(XmlDocument XMLDoc, XslCompiledTransform XSLTransform)
        {
            try
            {
                StringWriter sw = new StringWriter();
                XSLTransform.Transform(XMLDoc, null, sw);
                return sw.ToString().Replace("<?xml version=\"1.0\" encoding=\"utf-16\"?>", "").Replace("xmlns:asp=\"remove\"", "");

            }
            catch (System.Xml.Xsl.XsltException oXlstEx)
            {
                m_LastError = "XLST exception: " + oXlstEx.Message;
                m_LastReturnCode = Errorcode.XSLT_ERROR;
                return null;
            }
        }

        public XslCompiledTransform LoadXSLTresource(string m_sResource)
        {
            try
            {
                System.IO.StreamReader oPDF_XSLT = new System.IO.StreamReader(GetType().Assembly.GetManifestResourceStream("sCicero.xsl." + m_sResource + ".xslt"));
                System.Xml.Xsl.XslCompiledTransform oXSLT = new System.Xml.Xsl.XslCompiledTransform();
                System.Xml.XmlDocument oXd = new System.Xml.XmlDocument();
                oXd.LoadXml(oPDF_XSLT.ReadToEnd());
                oXSLT.Load(oXd);
                return oXSLT;
            }
            catch (Exception oEx)
            {
                m_LastError = "XSLT error: " + oEx.Message;
                m_LastReturnCode = Errorcode.XSLT_ERROR;
                return null;
            }
        }

        public XmlDocument LoadXmlresource(string sResource)
        {
            try
            {
                System.IO.StreamReader oXmlReader = new System.IO.StreamReader(GetType().Assembly.GetManifestResourceStream("sCicero.Resources." + sResource + ".xml"));
                System.Xml.XmlDocument oXd = new System.Xml.XmlDocument();
                oXd.LoadXml(oXmlReader.ReadToEnd());
                return oXd;
            }
            catch (Exception oEx)
            {
                m_LastError = "XML read error: " + oEx.Message;
                m_LastReturnCode = Errorcode.GENERAL_ERROR;
                return null;
            }
        }

        public XslCompiledTransform LoadXSLTfile(string m_sFileName, string sPath)
        {
            m_oXSLT = new XslCompiledTransform();
            m_oXSLT.Load(sPath + m_sFileName);
            return m_oXSLT;
        }

        public XslCompiledTransform LoadXSLTfile(string m_sFileName)
        {
            m_oXSLT = new XslCompiledTransform();
            m_oXSLT.Load(m_sFileName);
            return m_oXSLT;
        }

        public Errorcode Validate(XmlDocument oXML)
        {
            m_LastError = "";
            try
            {
             
                MemoryStream stmMemory = new MemoryStream();
                XmlTextWriter oXTW = new XmlTextWriter(stmMemory, Encoding.UTF8);
                oXML.WriteTo(oXTW);
                
                //Wrap the creation of the XmlReader in a 'using' block since
                //it implements IDisposable
                using (XmlReader xmlReader = XmlReader.Create(oXTW.BaseStream, xmlReaderSettings))
                {
                    if ( xmlReader != null )
                    {
                        while ( xmlReader.Read() )
                        {
                            //empty loop - if Read fails it will raise an error via the 
                            //ValidationEventHandler wired to the XmlReaderSettings object
                        }
                        
                        //explicitly call Close on the XmlReader to reduce strain on the GC
                        xmlReader.Close();
                    }
                }
            }
            catch(Exception oEx)
            {
                m_LastError = oEx.Message;
                return Errorcode.XML_SCHEMA_ERROR;
            }
            finally
            {

            }
            if (m_LastError != "")
            {
                return Errorcode.XML_SCHEMA_ERROR;
            }
            return Errorcode.NOERROR;
        }

        void xmlReaderSettings_ValidationEventHandler(object sender, ValidationEventArgs e)
        {
            m_LastError += e.Message + "\n";
        }

    }
}
